/*
  This file is part of 'Trivial chess'.

  'Trivial chess' is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  'Trivial chess' is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with 'Trivial chess'.  If not, see <http://www.gnu.org/licenses/>.
*/

/* SVN FILE: $Id$ */
/**
 * @author         $Author$
 * @version        $Rev$
 * @lastrevision   $Date$
 * @filesource     $URL$
 */

#ifndef PIECEABSTRACT_H_
#define PIECEABSTRACT_H_

#include "../EnumAbstract.h"

template<template<typename> class Piece, typename Int>
class PieceAbstract : public EnumAbstract<Piece<Int>, Int> {
public:
	static const Int COUNT = 6;
	static const Piece<Int> PAWN();
	static const Piece<Int> BISHOP();
	static const Piece<Int> KNIGHT();
	static const Piece<Int> ROOK();
	static const Piece<Int> QUEEN();
	static const Piece<Int> KING();
public:
	static const Piece<Int> BEGIN() { return Piece<Int>::PAWN(); }
	static const Piece<Int> RBEGIN() { return Piece<Int>::KING(); }
public:
	bool isPawn()   const { return this->me_c() == Piece<Int>::PAWN(); }
	bool isBishop() const { return this->me_c() == Piece<Int>::BISHOP(); }
	bool isKnight() const { return this->me_c() == Piece<Int>::KNIGHT(); }
	bool isRook()   const { return this->me_c() == Piece<Int>::ROOK(); }
	bool isQueen()  const { return this->me_c() == Piece<Int>::QUEEN(); }
	bool isKing()   const { return this->me_c() == Piece<Int>::KING(); }

	bool isMinor() const {
		return this->me_c().isBishop() || this->me_c().isKnight();
	}

	bool isMajor() const {
		return this->me_c().isRook() || this->me_c().isQueen();
	}

	bool isLeaper() const {
		return this->me_c().isKnight() || this->me_c().isKing();
	}

	bool isSlider() const {
		return this->me_c().isBishop()
				|| this->me_c().isRook()
				|| this->me_c().isQueen();
	}

	std::string toStr() const {
		std::string ret;
		if      ( this->me_c().isPawn() )   ret = "p";
		else if ( this->me_c().isBishop() ) ret = "b";
		else if ( this->me_c().isKnight() ) ret = "n";
		else if ( this->me_c().isRook() )   ret = "r";
		else if ( this->me_c().isQueen() )  ret = "q";
		else if ( this->me_c().isKing() )   ret = "k";
		else                                ret = "-";

		return ret;
	}

	void fromStr(const std::string str) {
		if      ( "p" == str ) this->me() = Piece<Int>::PAWN();
		else if ( "b" == str ) this->me() = Piece<Int>::BISHOP();
		else if ( "n" == str ) this->me() = Piece<Int>::KNIGHT();
		else if ( "r" == str ) this->me() = Piece<Int>::ROOK();
		else if ( "q" == str ) this->me() = Piece<Int>::QUEEN();
		else if ( "k" == str ) this->me() = Piece<Int>::KING();
		else                   this->me() = Piece<Int>::NIL();
	}
};

#endif /* PIECEABSTRACT_H_ */
